package com.hqu.ms;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.androidquery.AQuery;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.BDNotifyListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.ItemizedOverlay;
import com.baidu.mapapi.map.LocationData;
import com.baidu.mapapi.map.MKMapViewListener;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationOverlay;
import com.baidu.mapapi.map.OverlayItem;
import com.baidu.mapapi.utils.CoordinateConver;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.googlecode.androidannotations.annotations.AfterViews;
import com.googlecode.androidannotations.annotations.Background;
import com.googlecode.androidannotations.annotations.EFragment;
import com.googlecode.androidannotations.annotations.UiThread;
import com.googlecode.androidannotations.annotations.ViewById;
import com.googlecode.androidannotations.annotations.sharedpreferences.Pref;
import com.hqu.ms.detail.DetailActivity_;
import com.hqu.ms.entities.StoreEntivity;
import com.hqu.ms.entities.UserPrefs_;
import com.hqu.ms.utils.Constant;
import com.hqu.ms.utils.JSONResponse;
import com.hqu.ms.utils.JSONUtil;
import com.hqu.ms.utils.ToastUtils;
import com.hqu.ms.utils.JSONResponse.Status;


@EFragment(R.layout.ms_multi_location)
public class MultiLocFragment extends SherlockFragment{
	
	private final static int UPDATE_MAPVIEW = 11;
	private final static int NOT_UPDATE_MAPVIEW = 12;
	private final static int UPDATE_WITH_POINT = 13;
	
	private static final int LIST = Menu.FIRST;
	@Pref
	UserPrefs_ userPref;
	
	@ViewById(R.id.bmapView)
	MapView mMapView;
	
	@ViewById
	RelativeLayout rlLayout;
	
	@ViewById
	LinearLayout lllayout;
	
	@ViewById(R.id.nearby_shop_list_image)
	ImageView storeImage;
	
	@ViewById
	TextView tvLoading;
	
	@ViewById
	ImageView ivTemp;
	
	@ViewById(R.id.nearby_shop_list_title)
	TextView tvTitle;
	
	@ViewById(R.id.nearby_shop_list_location_text)
	TextView tvAddress;
	
	@ViewById(R.id.nearby_shop_list_location_distance)
	TextView tvDistance;
	
	public NotifyLister mNotifyer=null;
	private MapController mMapController;
	public MKMapViewListener mMapListener = null;
	public MyLocationListenner myListener = new MyLocationListenner();
	private static List<StoreEntivity> stores = new ArrayList<StoreEntivity>();
	private boolean needLoading = false;
	private boolean isFirst = true;
	LocationData locData = null;
	MyLocationOverlay myLocationOverlay = null;
	private boolean updateView = true;
	LocationClient mLocClient;
	
	private ProgressDialog pd ;
	static {
		StoreEntivity store = new StoreEntivity(11,"豪嘉基","华大后街豪嘉基","234679", 118.098930, 24.60704, 856.34);
		stores.add(store);
		store = new StoreEntivity(12, "辉仔记", "华大后街辉仔记", "324567", 118.098933, 24.60704, 923.78);
		stores.add(store);
		store = new StoreEntivity(13, "重庆火锅", "华大后街重庆火锅", "123456", 118.098932, 24.60703,886.90);
		stores.add(store);
		store = new StoreEntivity(14, "沙县小吃", "华大后加沙县小吃", "234567", 118.098934, 24.60705, 854.79);
		stores.add(store);
		
	}
	
	private Handler mHandler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case UPDATE_MAPVIEW:
				updateView = true;
				mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6)),
	            		mHandler.obtainMessage(NOT_UPDATE_MAPVIEW));
				break;
			case NOT_UPDATE_MAPVIEW:
				updateView = false;
				mLocClient.stop();
				
				getNearbyStore(null);
				break;
			case UPDATE_WITH_POINT:
				GeoPoint point = (GeoPoint) msg.obj;
				if(point != null){
					getNearbyStore(point);
				}
				break;
			default:
				break;
			}
		};
	};
	
	@AfterViews
	void afterViewInjected(){
		setHasOptionsMenu(true);
		rlLayout.setVisibility(View.INVISIBLE);
		tvLoading.setVisibility(View.VISIBLE);
		initMap();
//		showProgressDialog();
		
	}
	
	boolean isGettingData = false;
	@Background
	void getNearbyStore(GeoPoint point){
		synchronized (this) {
			if(isGettingData){
				return;
			}
			isGettingData = true;
			initStoreListData(point);
			isGettingData = false;
		}
		
	}
	
	/*@UiThread
	public void showProgressDialog(){
		if(pd != null && pd.isShowing()){
			return; 
		}
		pd = DialogUtils.getProgressDialog(getActivity(), "加载中...");
		pd.show();
	}
	
	@UiThread
	public void dismissProgressDialog(){
		if(pd != null && pd.isShowing()){
			pd.dismiss();
			pd = null;
		}
	}*/
	
	public void initStoreListData(GeoPoint point){
		boolean clear = false;
		JSONObject jsonData = new JSONObject();
		JSONResponse jsonResponse = null;
		try {
			jsonData.put("mg_page", 1);
			jsonData.put("order_way", 2);
			if(point == null){
				clear = false;
				jsonData.put("user_long", locData.longitude);//userPref.userLong().get());
				jsonData.put("user_lati", locData.latitude); //userPref.userLatit().get());
			}else{
				clear = true;
				jsonData.put("user_long", point.getLongitudeE6() * 0.1/(1E6));
				jsonData.put("user_lati", point.getLatitudeE6() * 0.1/(1E6));
			}
			jsonResponse = JSONUtil.postRequest(52, jsonData);
			if(jsonResponse.getStatus() != Status.ERR){
				JSONObject data = jsonResponse.getData();
				int status = -1;
				status = data.getInt("state");
				if(status == 2){
					JSONArray jsonArray = data.getJSONArray("msgGroupData");
					initShopInfoFromJson(jsonArray, clear);
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	
	public void initShopInfoFromJson(JSONArray jsonArray, boolean clear) throws JsonSyntaxException, JSONException{
		boolean needClear = false;
		if(clear){
//			if(stores.size() > 20){
//				stores.clear();
//				needClear = true;
//			}
		}
		Gson gson = new Gson();
		List<StoreEntivity> storeList = new ArrayList<StoreEntivity>();
		for(int i=0; i< jsonArray.length(); i++){
			StoreEntivity entivity = gson.fromJson(jsonArray.getString(i).toString(), StoreEntivity.class);
			for(int k=0; k<stores.size(); k++){
				if(!stores.get(k).getMg_name().equals(entivity.getMg_name())){
					storeList.add(entivity);
				}
			}
			
			
			Log.d("Store", entivity.toString());
		}
		
		if(isFirst){
			isFirst = !isFirst;
			addFirstOverlays(stores);
		}
		stores.addAll(storeList);
		addOverlays(needClear, storeList);
	}
	
	@UiThread
	public void addFirstOverlays(List<StoreEntivity> entivities){
		Drawable marker = getResources().getDrawable(R.drawable.ms_loc_point);
		if(overlay == null){
			overlay = new MSMultiOverlay(marker, this);
		}
		
		for(int i=0; i<entivities.size(); i++){
			StoreEntivity store = stores.get(i);
			GeoPoint geoPoint = new GeoPoint((int)(store.getMg_lati()* 1E6), 
				(int)(store.getMg_long()*1E6));
			
			OverlayItem mOverlayItem = new OverlayItem(geoPoint, store.getMg_name(), store.getMg_address());
			overlay.addItem(mOverlayItem);
			
		}
		
		mMapView.getOverlays().add(overlay);
		mMapView.refresh();
	}
	
	static MSMultiOverlay overlay ;
	@UiThread
	public void addOverlays(boolean needClear, List<StoreEntivity> storeList){
		Drawable marker = getResources().getDrawable(R.drawable.ms_loc_point);
		if(overlay == null){
			overlay = new MSMultiOverlay(marker, this);
		}
		if(needClear){
			mMapView.getOverlays().clear();
			mMapView.refresh();
			Log.d("addOverlay", "needClear<<<<<<<<");
		}else{
			Log.d("addOverlay", "do not needClear<<<<<<<");
		}
		for(int i=0; i<storeList.size(); i++){
			StoreEntivity store = stores.get(i);
			GeoPoint geoPoint = new GeoPoint((int)(store.getMg_lati()* 1E6), 
				(int)(store.getMg_long()*1E6));
			
			OverlayItem mOverlayItem = new OverlayItem(CoordinateConver.fromGcjToBaidu(geoPoint), store.getMg_name(), store.getMg_address());
			overlay.addItem(mOverlayItem);
			
		}
		
		mMapView.getOverlays().add(overlay);
		mMapView.refresh();
//		dismissProgressDialog();
		if(tvLoading.getVisibility() == View.VISIBLE){
			tvLoading.setVisibility(View.GONE);
		}
		if(tvLoading.getVisibility() == View.VISIBLE){
			tvLoading.setVisibility(View.GONE);
		}
	}
	
	
	void initMap() {
//		mLocClient = new LocationClient(getActivity());
		mLocClient = ((MSApp)getActivity().getApplication()).mLocationClient;
		mLocClient.registerLocationListener(myListener);

		mNotifyer = new NotifyLister();
		//Œ¨∂»lati   æ≠∂»Longi
		if(TextUtils.isEmpty(userPref.userCity().get())){
			mNotifyer.SetNotifyLocation(userPref.userLatit().get(), userPref.userLong().get(), 3000, "bd09ll");
		}else{
			mNotifyer.SetNotifyLocation(42.03249652949337, 113.3129895882556, 3000, "bd09ll");
		}
		mLocClient.registerNotify(mNotifyer);
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);
		option.setCoorType("bd09ll");
		option.setScanSpan(1000);
		mLocClient.setLocOption(option);
		mLocClient.start();

		mMapController = mMapView.getController();

		mMapView.setLongClickable(true);

		mMapView.getController().setZoom(16);
		mMapView.getController().enableClick(true);
		mMapView.displayZoomControls(true);

		mMapListener = new MKMapViewListener() {

			@Override
			public void onMapMoveFinish() {
				
			}

			@Override
			public void onClickMapPoi(MapPoi mapPoiInfo) {

				String title = "";
				if (mapPoiInfo != null) {
					title = mapPoiInfo.strText;
					showToast(title);
				}
			}
		};

		mMapView.regMapViewListener(MSApp.getInstance().mBMapManager, mMapListener);
		myLocationOverlay = new MyLocationOverlay(mMapView);
		locData = new LocationData();
	    myLocationOverlay.setData(locData);
		mMapView.getOverlays().add(myLocationOverlay);
		myLocationOverlay.enableCompass();
		mMapView.refresh();
		
		mMapView.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if(rlLayout.getVisibility() == View.VISIBLE){
					rlLayout.setVisibility(View.GONE);
				}
				float x =0f, y= 0f;
				switch (event.getAction()) {
				case MotionEvent.ACTION_UP:
					float xx = event.getX();
					float yy = event.getY();
					if((xx-x >= 50 || yy -y >= 50) && needLoading){
						updateData();
					}
					break;
				case MotionEvent.ACTION_DOWN:
					x = event.getX();
					y = event.getY();
					break;
				case MotionEvent.ACTION_MOVE:
					needLoading = true;
					tvLoading.setVisibility(View.VISIBLE);
					break;

				default:
					break;
				}
				return false;
			}
		});
	}
	
	
	public void updateData(){
		synchronized (mMapView) {
			needLoading = false;
			GeoPoint point = mMapView.getMapCenter();
			
			Message msg = new Message();
			msg.obj = point;
			msg.what = UPDATE_WITH_POINT;
			mHandler.sendMessage(msg);
			Log.d("GeoPoint", point.getLongitudeE6()+ "   "+point.getLatitudeE6());
		}
	}
	
	public class MyLocationListenner implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location == null)
                return ;
            
            locData.latitude = location.getLatitude();
            locData.longitude = location.getLongitude();
            locData.direction = 2.0f;
            locData.accuracy = location.getRadius();
            locData.direction = location.getDerect();
//            Log.d("loctest",String.format("before: lat: %f lon: %f", location.getLatitude(),location.getLongitude()));
           // GeoPoint p = CoordinateConver.fromGcjToBaidu(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6)));
          //  Log.d("loctest",String.format("before: lat: %d lon: %d", p.getLatitudeE6(),p.getLongitudeE6()));
            myLocationOverlay.setData(locData);
            mMapView.refresh();
            if(updateView){
            	
            	mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6)), mHandler.obtainMessage(NOT_UPDATE_MAPVIEW));
            }
        }
        
        public void onReceivePoi(BDLocation poiLocation) {
            if (poiLocation == null){
                return ;
            }
            
        }
    }
    
	public void showPop(int index){
		final StoreEntivity store = stores.get(index);
		if(store == null){
			return ;
		}
		tvTitle.setText(store.getMg_name());
		tvAddress.setText(store.getMg_address());
		float dis = (float) store.getMg_juli();
		float show = 0.f;
		if(dis/1000 > 0.0f){
			show = (float) (dis/1000 + (dis%1000.0)/1000);
		}else{
			show = (float) (dis%1000.0/1000);
		}
		
		tvDistance.setText(String.format(getActivity().getString(R.string.shop_distance_str), show));
		
		if(TextUtils.isEmpty(store.getMg_picture())){
			ivTemp.setVisibility(View.GONE);
			storeImage.setVisibility(View.GONE);
			tvTitle.setGravity(Gravity.CENTER);
			lllayout.setGravity(Gravity.CENTER);
		}else{
			ivTemp.setVisibility(View.VISIBLE);
			tvTitle.setGravity(Gravity.CENTER | Gravity.LEFT);
			lllayout.setGravity(Gravity.CENTER | Gravity.LEFT);
			AQuery aq = new AQuery(rlLayout);
			aq.id(R.id.nearby_shop_list_image).image(Constant.URL_MSGGROUP_SMALL + store.getMg_picture(), true, true);
		}
		rlLayout.setVisibility(View.VISIBLE);
		Animation anim = AnimationUtils.loadAnimation(getActivity(), R.anim.anim_right_in);
		rlLayout.startAnimation(anim);
		rlLayout.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				DetailActivity_.intent(getActivity()).store(store).start();
				((MultiLocationActivity)getActivity()).finishThis();
			}
		});
	}
	
    public class NotifyLister extends BDNotifyListener{
        public void onNotify(BDLocation mlocation, float distance) {
        	
        }
    }
	
	public class MSMultiOverlay extends ItemizedOverlay<OverlayItem>{
		
		public List<OverlayItem> mGeoList = new ArrayList<OverlayItem>();
		private Drawable marker;
		private MultiLocFragment mFragment;
		public MSMultiOverlay(Drawable marker,MultiLocFragment fragment) {
			super(marker);
			this.marker = marker;
			mFragment = fragment;
		    
			populate();
		}
		
		@Override
		protected boolean onTap(int index) {
			mFragment.showPop(index);
			super.onTap(index);
			return false;
		}

		@Override
		public boolean onTap(GeoPoint point, MapView mapView) {
			return super.onTap(point, mapView);
		}
		
		@Override
		protected OverlayItem createItem(int index) {
			return mGeoList.get(index);
		}

		@Override
		public int size() {
			return mGeoList.size();
		}
		
		public void addItem(OverlayItem item){
			mGeoList.add(item);
			populate();
		}
		
		
		public void removeItem(int index){
			mGeoList.remove(index);
			populate();
		}

		public void removeAll(){
			for(int i=0; i<mGeoList.size(); i++){
				mGeoList.remove(i);
				populate();
			}
		}
	}
	
	@UiThread
	void showToast(String msg){
		ToastUtils.showToast(getActivity(), msg);
	}
	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		View view = LayoutInflater.from(getActivity()).inflate(R.layout.ms_action_map_list, null);
		menu.add(0, LIST, 0, "¡–±Ìœ‘ æ")
		.setActionView(view)
		.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
		
		ImageView ivList = (ImageView)view.findViewById(R.id.ivList);
		ivList.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				((MultiLocationActivity) getActivity()).finishThis();
			}
		});
		
		ActionBar bar = getSherlockActivity().getSupportActionBar();
		bar.setBackgroundDrawable(getResources().getDrawable(
				R.drawable.titlebar_background));
		bar.setHomeButtonEnabled(true);
		bar.setDisplayUseLogoEnabled(true);
		bar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP,
				ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_TITLE);
		
	}

	@Override
	public void onPause() {
		mMapView.onPause();
		super.onPause();
	}
	
	@Override
	public void onResume() {
		mMapView.onResume();
		super.onResume();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			((MultiLocationActivity) getActivity()).finishThis();
			break;

		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

//	public static class ListActionProvider extends ActionProvider {
//		private MultiLocFragment fragment;
//		View view = null;
//
//		public ListActionProvider(MultiLocFragment mFragment, View mView) {
//			super(mFragment.getActivity());
//			fragment = mFragment;
//			this.view = mView;
//		}
//
//		@Override
//		public View onCreateActionView() {
//
//			return view;
//		}
//
//		@Override
//		public boolean onPerformDefaultAction() {
//			((MultiLocationActivity) fragment.getActivity()).finishThis();
//			return true;
//		}
//	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		mLocClient.stop();
		if(mMapView != null){
			mMapView.destroy();
			mMapView = null;
		}
	}

}
